/**
 * Copyright 2008-2009. Chongqing Communications Industry Services Co.,Ltd Information Technology Branch. All rights
 * reserved. <a>http://www.cqcis.com</a>
 */
package com.cqcis.uip.base.framework.core;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.eclipse.osgi.service.resolver.BundleDescription;
import org.eclipse.osgi.service.resolver.ExportPackageDescription;
import org.eclipse.osgi.service.resolver.ImportPackageSpecification;
import org.eclipse.osgi.service.resolver.PlatformAdmin;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.service.packageadmin.PackageAdmin;

import com.cqcis.uip.base.framework.utils.BundleStatePrintUtil;
import com.cqcis.uip.base.framework.utils.TimeUtil;

/**
 * bundle 描述
 * 
 * @author huangmy
 * @date   2008-4-10
 */
public class BundleInfoDescription {	
	private BundleContext context;
	
	public BundleInfoDescription(BundleContext context) {
		this.context = context;		
	}
	
	public String getDescription(Bundle bundle) {
		PackageAdmin pAdmin = getPackageAdminService();
		if (pAdmin == null) {
			return null;
		}
				
		StringBuffer buffer = new StringBuffer(256);
		buffer.append("[ID] ")
		      .append(bundle.getBundleId()).append("\n")
		      .append("[NAME] ").append(bundle.getSymbolicName()).append("\n")
		      .append("[LOCATION] ").append(bundle.getLocation()).append("\n")
		      .append("[LASTMODIFIED] ").append(TimeUtil.getTimeStr(new Date(bundle.getLastModified()))).append("\n")
		      .append("[STATE] ").append(getStateName(bundle)).append("\n");
		
		buffer.append("[IMPORT PACKAGES] ").append("\n").append(getImportPackagesNames(getImportPackages(bundle))).append("\n");
		buffer.append("[EXPORT PACKAGES] ").append("\n").append(getExportPackagesNames(getExportPackages(bundle))).append("\n");
		
		ServiceReference[] srs = bundle.getRegisteredServices();
		buffer.append("[PUBLISH SERVICES] ").append("\n").append(getServiceReferencesNames(srs)).append("\n");
		ServiceReference[] srsUse = bundle.getServicesInUse();
		buffer.append("[REFERENCE SERVICES] ").append("\n").append(getServiceReferencesNames(srsUse)).append("\n");
		
		buffer.append("[DEPENDENCIES BUNDLES] ").append("\n").append(getDependentsNames(getDependencies(bundle))).append("\n");		
		buffer.append("[DEPENDENTS BUNDLES] ").append("\n").append(getDependentsNames(getDependents(bundle))).append("\n");
		
		return buffer.toString();
	}
	
	/**
	 * 依赖哪些包
	 * 
	 * @param bundle
	 * @return
	 */
	private BundleDescription[] getDependencies(Bundle bundle) {
		List<BundleDescription> deps = new ArrayList<BundleDescription>();
		
		BundleDescription cbd = getBundleDescription(bundle);
		
		Bundle[] bundles = this.context.getBundles(); // 所有的bundle
		if (bundles != null) {
			for (Bundle b : bundles) {
				BundleDescription[] bds = getDependents(b); // 该bundle的所有被依赖
				if (bds != null) {
					for (BundleDescription bd : bds) {
						if (bd == cbd) { // 如果被依赖中有当前依赖, 加入
							deps.add(bd);
						}
					}
				}
			}
		}
		
		return deps.toArray(new BundleDescription[deps.size()]) ;
	}
		
	/**
	 * 被哪些包依赖
	 * 
	 * @param bundle
	 * @return
	 */
	private BundleDescription[] getDependents(Bundle bundle) {
		BundleDescription bd = getBundleDescription(bundle);
		if (bd != null) {
			return bd.getDependents();
		}
		
		return null;
	}
	
	/**
	 * 依赖包名
	 * 
	 * @param dts
	 * @return
	 */
	private String getDependentsNames(BundleDescription[] dts) {
		if (dts == null) {
			return null;
		}
		
		StringBuffer buffer = new StringBuffer();
		buffer.append("\t").append(BundleStatePrintUtil.title()).append("\n");		
		for (BundleDescription bd : dts) {
			buffer.append("\t").append(BundleStatePrintUtil.print(this.context.getBundle(bd.getBundleId()))).append("\n");
		}
				      
		return buffer.toString();
	}
	
	/**
	 * bundle的导入包列表
	 * 
	 * @param bundle
	 * @return
	 */
    private ImportPackageSpecification[] getImportPackages(Bundle bundle) {    	
    	BundleDescription bd = getBundleDescription(bundle);
		if (bd != null) {
			return bd.getImportPackages();
		}
		
		return null;
	}
    
    /**
     * 导入包名称列表
     * 
     * @param ips
     * @return
     */
    private String getImportPackagesNames(ImportPackageSpecification[] ips) {
    	if (ips == null || ips.length <= 0) {
			return null;
		}
    	
    	String trimStr = "Import-Package: ";
    	int trimStrLen = trimStr.length();
    	
		StringBuffer buffer = new StringBuffer();
		
		for (int i = 0; i < ips.length; i ++) {	
			ImportPackageSpecification sr = ips[i];
			
			String srStr = sr.toString();
			
			int index = srStr.indexOf(trimStr);
			if (index >= 0) {
				srStr = srStr.substring(index + trimStrLen);
			}
						
			buffer.append("\t").append(srStr);
			if (i < ips.length - 1) {
				buffer.append(", \n");
			}
		}
		
		return buffer.toString();
    }
    
    /**
     * 导出包列表
     * 
     * @param epd
     * @return
     */
    private String getExportPackagesNames(ExportPackageDescription[] epd) {
    	if (epd == null || epd.length <= 0) {
			return null;
		}
    	
    	String trimStr = "Export-Package: ";
    	int trimStrLen = trimStr.length();
    	
		StringBuffer buffer = new StringBuffer();
		
		for (int i = 0; i < epd.length; i ++) {	
			ExportPackageDescription sr = epd[i];
			
			String srStr = sr.toString();
			
			int index = srStr.indexOf(trimStr);
			if (index >= 0) {
				srStr = srStr.substring(index + trimStrLen);
			}
			
			buffer.append("\t").append(srStr);
			if (i < epd.length - 1) {
				buffer.append(", \n");
			}
		}
		
		return buffer.toString();
    }
    
    /**
     * 导出包列表
     * 
     * @param bundle
     * @return
     */
    private ExportPackageDescription[] getExportPackages(Bundle bundle) {    	
    	BundleDescription bd = getBundleDescription(bundle);
		if (bd != null) {
			return bd.getExportPackages();
		}
		
		return null;
	}
    
    /**
     * bundle基本描述
     * 
     * @param bundle
     * @return
     */
    private BundleDescription getBundleDescription(Bundle bundle) {
    	PlatformAdmin pa = getPlatformAdminService();
		if (pa != null) {
			return pa.getState().getBundle(bundle.getBundleId());			
		}
		
		return null;
    }
	
	/**
	 * 状态名
	 * 
	 * @param bundle
	 * @return
	 */
	private String getStateName(Bundle bundle) {
		return BundleStatePrintUtil.getStateName(bundle);
	}
	
	/**
	 * 获取包管理服务
	 * 
	 * @return
	 */
	private PackageAdmin getPackageAdminService() {
		ServiceReference sr = this.context.getServiceReference(PackageAdmin.class.getName());
		if (sr == null) {
			return null;
		}
		
		return (PackageAdmin)this.context.getService(sr);
	}
	
	/**
	 * 服务名
	 * 
	 * @param srs
	 * @return
	 */
	private String getServiceReferencesNames(ServiceReference[] srs) {
		if (srs == null || srs.length <= 0) {
			return null;
		}
		StringBuffer buffer = new StringBuffer();
		
		for (int i = 0; i < srs.length; i ++) {	
			ServiceReference sr = srs[i];
			buffer.append("\t").append(sr);
			if (i < srs.length - 1) {
				buffer.append(", \n");
			}
		}
		
		return buffer.toString();
	}
	
	/**
	 * 平台管理服务
	 * 
	 * @return
	 */
	private PlatformAdmin getPlatformAdminService() {
		ServiceReference sr = this.context.getServiceReference(PlatformAdmin.class.getName());
		if (sr == null) {
			return null;
		}
		
		return (PlatformAdmin)this.context.getService(sr);
	}
}
